home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / gtlayout-source.lha / LTP_TabClass.c < prev    next >
C/C++ Source or Header  |  1996-10-11  |  17KB  |  832 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1996 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #if defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  15.  
  16. #define TIA_Labels        (TAG_USER+0x90000)
  17. #define TIA_Font        (TAG_USER+0x90001)
  18. #define TIA_Screen        (TAG_USER+0x90002)
  19. #define TIA_Index        (TAG_USER+0x90003)
  20. #define TIA_DrawInfo    (TAG_USER+0x90004)
  21. #define TIA_SizeType    (TAG_USER+0x90005)
  22.  
  23. STATIC VOID
  24. DrawCap(struct RastPort *RPort,LONG Left,LONG Top,LONG Width,LONG Height,BOOL Flip)
  25. {
  26.     LONG x,y,da,MidX,MidY,r,Full,Push,Mult;
  27.  
  28.     Full = Height;
  29.  
  30.     Height = Width;
  31.  
  32.     MidX = Left;
  33.     MidY = Top + Height - 1;
  34.  
  35.     r = Height - 1;
  36.  
  37.     x = 0;
  38.     y = r;
  39.     da = r - 1;
  40.  
  41.     if(Flip)
  42.     {
  43.         Push = Width - 1;
  44.         Mult = -1;
  45.     }
  46.     else
  47.     {
  48.         Push = 0;
  49.         Mult = 1;
  50.     }
  51.  
  52.     do
  53.     {
  54.         if(da < 0)
  55.         {
  56.             y--;
  57.  
  58.             da += y * 2;
  59.         }
  60.  
  61.         WritePixel(RPort,Left + Push + Mult * (x + MidX - Left),-y + MidY);
  62.         WritePixel(RPort,Left + Push + Mult * (y + MidX - Left),-x + MidY);
  63.  
  64.         da -= (1 + x * 2);
  65.  
  66.         x++;
  67.     }
  68.     while(x <= y);
  69.  
  70.     Left += Width - 1 - Push;
  71.  
  72. /*    This is what it used to be. Easily catches fire, take care
  73.  
  74.     if(Flip)
  75.     {
  76.         do
  77.         {
  78.             if(da < 0)
  79.             {
  80.                 y--;
  81.  
  82.                 da += y * 2;
  83.             }
  84.  
  85.             WritePixel(RPort,Left + Width - 1 - (x + MidX - Left),-y + MidY);
  86.             WritePixel(RPort,Left + Width - 1 - (y + MidX - Left),-x + MidY);
  87.  
  88.             da -= (1 + x * 2);
  89.  
  90.             x++;
  91.         }
  92.         while(x <= y);
  93.     }
  94.     else
  95.     {
  96.         do
  97.         {
  98.             if(da < 0)
  99.             {
  100.                 y--;
  101.  
  102.                 da += y * 2;
  103.             }
  104.  
  105.             WritePixel(RPort,x + MidX,-y + MidY);
  106.             WritePixel(RPort,y + MidX,-x + MidY);
  107.  
  108.             da -= (1 + x * 2);
  109.  
  110.             x++;
  111.         }
  112.         while(x <= y);
  113.  
  114.         Left += Width - 1;
  115.     }
  116. */
  117.     LTP_DrawLine(RPort,Left,Top + Height,Left,Top + Full - 1);
  118. }
  119.  
  120. STATIC VOID
  121. RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,LONG Pull)
  122. {
  123.     LONG    Width,Height;
  124.     LONG    i;
  125.     LONG    Pen;
  126.  
  127.     Width    = Info->TabWidth;
  128.     Height    = Info->TabHeight;
  129.  
  130.     SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
  131.  
  132.     for(i = 0 ; i < 4 ; i++)
  133.     {
  134.         if(i & 1)
  135.         {
  136.             if(Pens[SHINEPEN] == Pens[SHADOWPEN])
  137.                 Pen = BACKGROUNDPEN;
  138.             else
  139.                 Pen = SHADOWPEN;
  140.         }
  141.         else
  142.             Pen = SHINEPEN;
  143.  
  144.         LTP_SetAPen(&Info->RPort,Pens[Pen]);
  145.  
  146.         LTP_DrawLine(&Info->RPort,0,Height - 1 - i,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
  147.     }
  148.  
  149.     for(i = Info->Count - 1 ; i >= 0 ; i--)
  150. //    for(i = 0 ; i < Info->Count ; i++)
  151.     {
  152.         if(i != Info->Current)
  153.             BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
  154.     }
  155.  
  156.     BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
  157.  
  158.     WaitBlit();
  159.  
  160.     BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
  161. }
  162.  
  163. STATIC VOID
  164. SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  165. {
  166.     TabInfo            *Info = INST_DATA(class,gadget);
  167.     struct TagItem    *Tag;
  168.     BOOL             NeedRefresh = FALSE;
  169.     BOOL             Disabled;
  170.  
  171.     Disabled = (BOOL)((gadget->Flags & GFLG_DISABLED) != 0);
  172.  
  173.     if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
  174.     {
  175.         if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
  176.             NeedRefresh = TRUE;
  177.     }
  178.  
  179.     if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
  180.     {
  181.         LONG Index = Tag->ti_Data;
  182.  
  183.         if(Index >= Info->Count)
  184.             Index = Info->Count - 1;
  185.  
  186.         if(Index != Info->Current)
  187.         {
  188.             Info->Initial = Info->Current = Index;
  189.  
  190.             NeedRefresh = TRUE;
  191.         }
  192.     }
  193.  
  194.     if(NeedRefresh)
  195.     {
  196.         struct RastPort *RPort;
  197.  
  198.         if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
  199.         {
  200.             DoMethod((Object *)gadget,GM_RENDER,SetInfo->ops_GInfo,RPort,GREDRAW_REDRAW);
  201.  
  202.             ReleaseGIRPort(RPort);
  203.         }
  204.     }
  205. }
  206.  
  207. STATIC ULONG
  208. RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
  209. {
  210.     TabInfo *Info = INST_DATA(class,gadget);
  211.  
  212.     RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,RenderInfo->gpr_Redraw == GREDRAW_UPDATE ? 2 : 0);
  213.  
  214.     return(TRUE);
  215. }
  216.  
  217. STATIC VOID
  218. DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
  219. {
  220.     TabInfo *Info = INST_DATA(class,gadget);
  221.  
  222.     if(Info->Mask || Info->Tabs || Info->BitMap)
  223.         WaitBlit();
  224.  
  225.     if(Info->Mask)
  226.     {
  227.         if(Info->ChipMask)
  228.             FreeVec(Info->Mask);
  229.         else
  230.             FreeRaster(Info->Mask,Info->TabWidth,Info->TabHeight);
  231.     }
  232.  
  233.     if(Info->Tabs)
  234.     {
  235.         LONG i;
  236.  
  237.         for(i = 0 ; i < Info->Count ; i++)
  238.             LTP_DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
  239.  
  240.         FreeVec(Info->Tabs);
  241.     }
  242.  
  243.     LTP_DeleteBitMap(Info->BitMap,FALSE);
  244. }
  245.  
  246. STATIC ULONG
  247. NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  248. {
  249.     if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
  250.     {
  251.         TabInfo            *Info = INST_DATA(class,gadget);
  252.         struct TagItem    *Tag,*TagList = SetInfo->ops_AttrList;
  253.         struct TextAttr    *FontAttr;
  254.         LONG             Width,Height;
  255.         struct DrawInfo    *DrawInfo;
  256.         STRPTR            *Labels;
  257.         struct Screen    *Screen;
  258.  
  259.         Width        = 0;
  260.         Height        = 0;
  261.  
  262.         FontAttr    = NULL;
  263.         DrawInfo    = NULL;
  264.         Labels        = NULL;
  265.         Screen        = NULL;
  266.  
  267.         memset(Info,0,sizeof(TabInfo));
  268.  
  269.         while(Tag = NextTagItem(&TagList))
  270.         {
  271.             switch(Tag->ti_Tag)
  272.             {
  273.                 case GA_Width:
  274.                     Width = Tag->ti_Data;
  275.                     break;
  276.  
  277.                 case GA_Height:
  278.                     Height = Tag->ti_Data;
  279.                     break;
  280.  
  281.                 case TIA_Labels:
  282.                     Labels = (STRPTR *)Tag->ti_Data;
  283.                     break;
  284.  
  285.                 case TIA_Font:
  286.                     FontAttr = (struct TextAttr *)Tag->ti_Data;
  287.                     break;
  288.  
  289.                 case TIA_Screen:
  290.                     Screen = (struct Screen *)Tag->ti_Data;
  291.                     break;
  292.  
  293.                 case TIA_Index:
  294.                     Info->Current = Tag->ti_Data;
  295.                     break;
  296.  
  297.                 case TIA_DrawInfo:
  298.                     DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  299.                     break;
  300.             }
  301.         }
  302.  
  303.         if(Labels)
  304.         {
  305.             while(Labels[Info->Count])
  306.                 Info->Count++;
  307.         }
  308.  
  309.         if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
  310.         {
  311.             struct TextFont *Font;
  312.  
  313.             if(Font = OpenFont(FontAttr))
  314.             {
  315.                 struct RastPort *RPort = &Info->RPort;
  316.  
  317.                 InitRastPort(RPort);
  318.  
  319.                 SetFont(RPort,Font);
  320.  
  321.                 if(Height >= RPort->TxHeight + 11)
  322.                 {
  323.                     LONG i,Len,MaxWidth,Remain;
  324.                     LONG Lean;
  325.  
  326.                     if(Info->Current < 0)
  327.                         Info->Current = 0;
  328.                     else
  329.                     {
  330.                         if(Info->Current >= Info->Count)
  331.                             Info->Current = Info->Count - 1;
  332.                     }
  333.  
  334.                     Lean = (TextLength(RPort,"O",1) + 1) / 2;
  335.  
  336.                     Info->Thick    = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  337.  
  338.                     if(Info->Thick < 1)
  339.                         Info->Thick = 1;
  340.  
  341.                     for(i = MaxWidth = 0 ; i < Info->Count ; i++)
  342.                     {
  343.                         if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  344.                             MaxWidth = Len;
  345.                     }
  346.  
  347.                     MaxWidth = Info->Thick + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + Info->Thick;
  348.  
  349.                     Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
  350.  
  351.                     if(Remain >= Info->Count - 1)
  352.                     {
  353.                         if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
  354.                         {
  355.                             STATIC BYTE PenNumbers[] =
  356.                             {
  357.                                 BACKGROUNDPEN,
  358.                                 SHINEPEN,
  359.                                 SHADOWPEN,
  360.                                 TEXTPEN
  361.                             };
  362.  
  363.                             struct BitMap     Mask;
  364.                             LONG             Depth;
  365.                             LONG             MaxPen;
  366.                             UWORD            *Pens = DrawInfo->dri_Pens;
  367.                             BOOL             GotIt = TRUE;
  368.  
  369.                             for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
  370.                             {
  371.                                 if(Pens[PenNumbers[i]] > MaxPen)
  372.                                     MaxPen = Pens[PenNumbers[i]];
  373.                             }
  374.  
  375.                             for(i = 1 ; i < 9 ; i++)
  376.                             {
  377.                                 if(MaxPen < (1 << i))
  378.                                 {
  379.                                     Depth = i;
  380.                                     break;
  381.                                 }
  382.                             }
  383.  
  384.                             Info->TabWidth    = MaxWidth;
  385.                             Info->TabHeight    = 4 + RPort->TxHeight + 5;
  386.  
  387.                             InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
  388.  
  389.                             Mask.Planes[1] = NULL;
  390.  
  391.                             for(i = 0 ; GotIt && i < 2 ; i++)
  392.                             {
  393.                                 if(!(Mask.Planes[i] = (PLANEPTR)AllocRaster(Info->TabWidth,Info->TabHeight)))
  394.                                     GotIt = FALSE;
  395.                             }
  396.  
  397.                             if(GotIt)
  398.                             {
  399.                                 ULONG Type;
  400.  
  401.                                 Type = MEMF_CHIP;
  402.  
  403.                                 for(i = 0 ; i < 2 ; i++)
  404.                                     Type &= TypeOfMem(Mask.Planes[i]);
  405.  
  406.                                 if(!(Type & MEMF_CHIP))
  407.                                 {
  408.                                     LONG PageSize;
  409.  
  410.                                     for(i = 0 ; i < 2 ; i++)
  411.                                     {
  412.                                         FreeRaster(Mask.Planes[i],Info->TabWidth,Info->TabHeight);
  413.                                         Mask.Planes[i] = NULL;
  414.                                     }
  415.  
  416.                                     PageSize = Mask.BytesPerRow * Mask.Rows;
  417.  
  418.                                     for(i = 0 ; i < 2 ; i++)
  419.                                     {
  420.                                         if(!(Mask.Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_CHIP)))
  421.                                             GotIt = FALSE;
  422.                                     }
  423.  
  424.                                     Info->ChipMask = TRUE;
  425.                                 }
  426.                             }
  427.  
  428.                             for(i = 0 ; GotIt && i < Info->Count ; i++)
  429.                             {
  430.                                 if(!(Info->Tabs[i].BitMap = LTP_CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
  431.                                     GotIt = FALSE;
  432.                             }
  433.  
  434.                             if(GotIt)
  435.                             {
  436.                                 Depth = LTP_GetDepth(Screen->RastPort.BitMap);
  437.  
  438.                                 if(!(Info->BitMap = LTP_CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
  439.                                     GotIt = FALSE;
  440.                             }
  441.  
  442.                             if(GotIt)
  443.                             {
  444.                                 struct TmpRas     TmpRas;
  445.                                 LONG             j,Len,Offset,Pos;
  446.  
  447.                                 InitTmpRas(&TmpRas,Mask.Planes[1],RASSIZE(Info->TabWidth,Info->TabHeight));
  448.  
  449.                                 RPort->TmpRas    = &TmpRas;
  450.                                 RPort->BitMap    = &Mask;
  451.  
  452.                                 SetRast(RPort,0);
  453.  
  454.                                 LTP_SetPens(RPort,1,0,JAM1);
  455.  
  456.                                 DrawCap(RPort,0,0,Lean,Info->TabHeight,TRUE);
  457.                                 LTP_DrawLine(RPort,Lean,0,Info->TabWidth - (Lean + 1),0);
  458.  
  459.                                 DrawCap(RPort,Info->TabWidth - Lean,0,Lean,Info->TabHeight,FALSE);
  460.                                 LTP_DrawLine(RPort,0,Info->TabHeight - 1,Info->TabWidth - 1,Info->TabHeight - 1);
  461.  
  462.                                 Flood(RPort,1,Info->TabWidth / 2,Info->TabHeight / 2);
  463.  
  464.                                 LTP_SetAPen(RPort,0);
  465.  
  466.                                 for(i = 0 ; i < 2 ; i++)
  467.                                 {
  468.                                     for(j = 0 ; j < Info->Thick ; j++)
  469.                                         WritePixel(RPort,j,Info->TabHeight - 1 - i);
  470.  
  471.                                     for(j = 0 ; j < Info->Thick ; j++)
  472.                                         WritePixel(RPort,Info->TabWidth - 1 - j,Info->TabHeight - 1 - i);
  473.                                 }
  474.  
  475.                                 WaitBlit();
  476.  
  477.                                 if(Info->ChipMask)
  478.                                     FreeVec(Mask.Planes[1]);
  479.                                 else
  480.                                     FreeRaster(Mask.Planes[1],Info->TabWidth,Info->TabHeight);
  481.  
  482.                                     // *VERY* important; leaving a dead TmpRas around will
  483.                                     // cause problems with Text() later as Gfx may use
  484.                                     // RPort->TmpRas for buffering.
  485.  
  486.                                 RPort->TmpRas = NULL;
  487.  
  488.                                 Offset = (Width - Info->Thick * 5) / Info->Count;
  489.  
  490.                                 while(Offset > 0 && Offset * (Info->Count - 1) + Info->TabWidth >= Width - Info->Thick * 5)
  491.                                     Offset--;
  492.  
  493.                                 if(Offset > Info->TabWidth + Info->Thick)
  494.                                     Offset = Info->TabWidth + Info->Thick;
  495.  
  496.                                 Pos = 2 * Info->Thick;
  497.  
  498.                                 for(i = 0 ; i < Info->Count ; i++)
  499.                                 {
  500.                                     RPort->BitMap = Info->Tabs[i].BitMap;
  501.  
  502.                                     Info->Tabs[i].Left = Pos;
  503.                                     Pos += Offset;
  504.  
  505.                                     SetRast(RPort,Pens[BACKGROUNDPEN]);
  506.  
  507.                                     LTP_SetAPen(RPort,Pens[SHINEPEN]);
  508.  
  509.                                     for(j = 0 ; j < Info->Thick ; j++)
  510.                                         DrawCap(RPort,Info->Thick + j,0,Lean,Info->TabHeight,TRUE);
  511.  
  512.                                     LTP_DrawLine(RPort,Info->Thick + Lean,0,Info->TabWidth - (Lean + 1) - Info->Thick,0);
  513.  
  514.                                     LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  515.  
  516.                                     for(j = 0 ; j < Info->Thick ; j++)
  517.                                         DrawCap(RPort,Info->TabWidth - Lean - j - Info->Thick,0,Lean,Info->TabHeight,FALSE);
  518.  
  519.                                     LTP_SetAPen(RPort,Pens[TEXTPEN]);
  520.                                     Len = strlen(Labels[i]);
  521.  
  522.                                     LTP_PrintText(RPort,Labels[i],Len,(Info->TabWidth - TextLength(RPort,Labels[i],Len)) / 2,2);
  523.                                 }
  524.  
  525.                                 Info->Mask = Mask.Planes[0];
  526.  
  527.                                 Info->Offset = Offset;
  528.  
  529.                                 Info->RPort.BitMap = Info->BitMap;
  530.  
  531.                                 CloseFont(Font);
  532.  
  533.                                 return((ULONG)gadget);
  534.                             }
  535.                         }
  536.                     }
  537.                 }
  538.  
  539.                 CloseFont(Font);
  540.             }
  541.         }
  542.  
  543.         CoerceMethod(class,(Object *)gadget,OM_DISPOSE);
  544.     }
  545.  
  546.     return(0);
  547. }
  548.  
  549. STATIC ULONG
  550. InputMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  551. {
  552.     TabInfo    *Info    = INST_DATA(class,gadget);
  553.     ULONG     Result    = GMR_MEACTIVE;
  554.     LONG     x,y;
  555.     BOOL     Done    = FALSE;
  556.  
  557.     x = InputInfo->gpi_Mouse.X;
  558.     y = InputInfo->gpi_Mouse.Y;
  559.  
  560.     if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  561.     {
  562.         if(InputInfo->gpi_IEvent->ie_Code == MENUDOWN)
  563.         {
  564.             Result    = GMR_NOREUSE;
  565.             Done    = TRUE;
  566.         }
  567.         else
  568.         {
  569.             if(InputInfo->gpi_IEvent->ie_Code == SELECTUP)
  570.             {
  571.                 Done = TRUE;
  572.  
  573.                 if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  574.                 {
  575.                     Result = GMR_NOREUSE | GMR_VERIFY;
  576.  
  577.                     *InputInfo->gpi_Termination = Info->Current;
  578.                 }
  579.                 else
  580.                     Result = GMR_NOREUSE;
  581.             }
  582.         }
  583.     }
  584.  
  585.     if(Result == GMR_NOREUSE)
  586.     {
  587.         struct RastPort    *RPort;
  588.  
  589.         if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  590.         {
  591.             Info->Current = Info->Initial;
  592.  
  593.             DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_REDRAW);
  594.  
  595.             ReleaseGIRPort(RPort);
  596.         }
  597.     }
  598.  
  599.     if(!Done)
  600.     {
  601.         if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  602.         {
  603.             LONG Index,i;
  604.  
  605.             for(Index = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  606. //            for(Index = -1, i = 0 ; i < Info->Count ; i++)
  607.             {
  608.                 if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  609.                     Index = i;
  610.             }
  611.  
  612.             if(Index != Info->Current && Index != -1)
  613.             {
  614.                 struct RastPort    *RPort;
  615.  
  616.                 if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  617.                 {
  618.                     Info->Current = Index;
  619.  
  620.                     DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_UPDATE);
  621.  
  622.                     ReleaseGIRPort(RPort);
  623.                 }
  624.             }
  625.         }
  626.     }
  627.  
  628.     return(Result);
  629. }
  630.  
  631. STATIC ULONG
  632. ActiveMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  633. {
  634.     TabInfo            *Info = INST_DATA(class,gadget);
  635.     struct RastPort    *RPort;
  636.  
  637.     if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  638.     {
  639.         LONG Current,i;
  640.         LONG x;
  641.  
  642.         x = InputInfo->gpi_Mouse.X;
  643.  
  644.         for(Current = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  645. //        for(Current = -1, i = 0 ; i < Info->Count ; i++)
  646.         {
  647.             if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  648.                 Current = i;
  649.         }
  650.  
  651.         Info->Initial = Info->Current;
  652.  
  653.         if(Current != Info->Current && Current != -1)
  654.         {
  655.             Info->Current = Current;
  656.  
  657.             DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_UPDATE);
  658.         }
  659.  
  660.         ReleaseGIRPort(RPort);
  661.  
  662.         return(GMR_MEACTIVE);
  663.     }
  664.     else
  665.         return(GMR_NOREUSE);
  666. }
  667.  
  668. STATIC ULONG
  669. InactiveMethod(struct IClass *class,struct Gadget *gadget,struct gpGoInactive *InactiveInfo)
  670. {
  671.     TabInfo            *Info = INST_DATA(class,gadget);
  672.     struct RastPort    *RPort;
  673.     LONG             Index;
  674.  
  675.     if(InactiveInfo->gpgi_Abort)
  676.         Index = Info->Initial;
  677.     else
  678.         Index = Info->Current;
  679.  
  680.     if(RPort = ObtainGIRPort(InactiveInfo->gpgi_GInfo))
  681.     {
  682.         Info->Current = Index;
  683.  
  684.         DoMethod((Object *)gadget,GM_RENDER,InactiveInfo->gpgi_GInfo,RPort,GREDRAW_REDRAW);
  685.  
  686.         ReleaseGIRPort(RPort);
  687.     }
  688.  
  689.     return(0);
  690. }
  691.  
  692. BOOL
  693. LTP_ObtainTabSize(struct IBox *Box,...)
  694. {
  695.     va_list             VarArgs;
  696.     struct TagItem    *TagList,*Tag;
  697.     struct TextAttr    *FontAttr;
  698.     struct DrawInfo    *DrawInfo;
  699.     STRPTR            *Labels;
  700.     LONG             Count;
  701.     LONG             SizeType;
  702.     BOOL             Success;
  703.  
  704.     Success = FALSE;
  705.  
  706.     va_start(VarArgs,Box);
  707.  
  708.     TagList = (struct TagItem *)VarArgs;
  709.  
  710.     SizeType = GDOMAIN_NOMINAL;
  711.     FontAttr = NULL;
  712.     DrawInfo = NULL;
  713.     Labels = NULL;
  714.  
  715.     while(Tag = NextTagItem(&TagList))
  716.     {
  717.         switch(Tag->ti_Tag)
  718.         {
  719.             case TIA_Labels:
  720.                 Labels = (STRPTR *)Tag->ti_Data;
  721.                 break;
  722.  
  723.             case TIA_Font:
  724.                 FontAttr = (struct TextAttr *)Tag->ti_Data;
  725.                 break;
  726.  
  727.             case TIA_DrawInfo:
  728.                 DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  729.                 break;
  730.  
  731.             case TIA_SizeType:
  732.                 SizeType = Tag->ti_Data;
  733.                 break;
  734.         }
  735.     }
  736.  
  737.     Count = 0;
  738.  
  739.     if(Labels)
  740.     {
  741.         while(Labels[Count])
  742.             Count++;
  743.     }
  744.  
  745.     if(DrawInfo && FontAttr && Labels && Count)
  746.     {
  747.         struct TextFont *Font;
  748.  
  749.         if(Font = OpenFont(FontAttr))
  750.         {
  751.             struct RastPort    RastPort,*RPort = &RastPort;
  752.             LONG            i,Len,MaxWidth;
  753.             LONG            Lean,Thick;
  754.  
  755.             InitRastPort(RPort);
  756.  
  757.             SetFont(RPort,Font);
  758.  
  759.             Box->Left    = 0;
  760.             Box->Top    = 0;
  761.             Box->Height    = RPort->TxHeight + 11;
  762.  
  763.             Lean = (TextLength(RPort,"O",1) + 1) / 2;
  764.  
  765.             Thick = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  766.  
  767.             if(Thick < 1)
  768.                 Thick = 1;
  769.  
  770.             for(i = MaxWidth = 0 ; i < Count ; i++)
  771.             {
  772.                 if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  773.                     MaxWidth = Len;
  774.             }
  775.  
  776.             MaxWidth = 2 + (Lean + Thick - 1 + Thick + MaxWidth + Thick + Lean + Thick - 1) + 2;
  777.  
  778.             if(SizeType == GDOMAIN_MINIMUM && Count > 1)
  779.                 Box->Width = 2 * Thick + MaxWidth + (Count - 1) * (Thick * 4) + Thick * 3;
  780.             else
  781.                 Box->Width = 2 * Thick + Count * (MaxWidth + Thick) + Thick * 2;
  782.  
  783.             CloseFont(Font);
  784.  
  785.             Success = TRUE;
  786.         }
  787.     }
  788.  
  789.     va_end(VarArgs);
  790.  
  791.     return(Success);
  792. }
  793.  
  794. ULONG SAVE_DS ASM
  795. LTP_TabClassDispatcher(REG(a0) struct IClass *class,REG(a2) Object *object,REG(a1) Msg msg)
  796. {
  797.     switch(msg->MethodID)
  798.     {
  799.         case OM_NEW:
  800.             return(NewMethod(class,(struct Gadget *)object,(struct opSet *)msg));
  801.  
  802.         case OM_UPDATE:
  803.         case OM_SET:
  804.             SetMethod(class,(struct Gadget *)object,(struct opSet *)msg);
  805.             break;
  806.  
  807.         case GM_RENDER:
  808.             return(RenderMethod(class,(struct Gadget *)object,(struct gpRender *)msg));
  809.  
  810.         case GM_HITTEST:
  811.             return(GMR_GADGETHIT);
  812.  
  813.         case GM_GOINACTIVE:
  814.             return(InactiveMethod(class,(struct Gadget *)object,(struct gpGoInactive *)msg));
  815.  
  816.         case GM_HANDLEINPUT:
  817.             return(InputMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  818.  
  819.         case GM_GOACTIVE:
  820.             return(ActiveMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  821.  
  822.         case OM_DISPOSE:
  823.             DisposeMethod(class,(struct Gadget *)object,msg);
  824.  
  825.             // Falls down through to the default case...
  826.     }
  827.  
  828.     return(DoSuperMethodA(class,object,msg));
  829. }
  830.  
  831. #endif    // defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  832.